package com.jwong.client.feign.fallback;

import com.alibaba.fastjson.JSON;
import com.jwong.client.feign.AuthorizationFeignClient;
import com.jwong.common.entity.FeignResponseErrorBody;
import com.jwong.common.util.StringUtils;
import feign.FeignException;
import feign.hystrix.FallbackFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.Optional;

@Component
public class AuthorizationFeignClientFallbackFactory implements FallbackFactory<AuthorizationFeignClient> {

    @Override
    public AuthorizationFeignClient create(Throwable cause) {

        return new AuthorizationFeignClient() {

            @Override
            public ResponseEntity<Object> tokenPasswordUsername(String username, String password,
                                                                String grant_type, String authorization) {
                return errorResponse();
            }

            @Override
            public ResponseEntity<Object> tokenSmsCode(String mobile, String smsCode,
                                                       String grant_type, String authorization) {
                return errorResponse();
            }

            private ResponseEntity<Object> errorResponse() {
                if (cause instanceof FeignException) {
                    FeignException throwable = (FeignException)cause;
                    Optional<ByteBuffer> byteBuffer = throwable.responseBody();
                    if (byteBuffer.isPresent()) {
                        ByteArrayInputStream inputStream = new ByteArrayInputStream(byteBuffer.get().array());
                        String bodyMessage = StringUtils.inputStream2String(inputStream);

                        FeignResponseErrorBody errorBody = JSON.parseObject(bodyMessage, FeignResponseErrorBody.class);
                        HttpStatus httpStatus = HttpStatus.resolve(throwable.status());
                        return new ResponseEntity<>(
                                errorBody, httpStatus == null ? HttpStatus.INTERNAL_SERVER_ERROR : httpStatus);
                    }
                }
                return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
            }

        };

    }
}